package cn.benma666.sjsj.myutils;

import cn.benma666.iframe.BasicObject;
import cn.benma666.iframe.InterfaceThreadPool;
import cn.benma666.vo.TPConfig;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * 线程池配置
 */
@Configuration("myThreadConfig")
@EnableAsync
@ConditionalOnProperty("thread-pool.enabled")
@ConfigurationProperties(prefix = "thread-pool")
@Setter
@Getter
public class ThreadPool extends BasicObject implements InterfaceThreadPool {
    private static int corePoolSize;
    private static int maxPoolSize;
    private static int keepAliveSeconds;
    private static int queueCapacity;
    private static String threadNamePrefix;
    /**
     * 线程池集合
     */
    private static Map<String,ThreadPool> threadMap = new HashMap<>();
    /**
     * 线程池对象
     */
    private ThreadPoolTaskExecutor executor;

    public ThreadPool(){}

    public ThreadPool(ThreadPoolTaskExecutor executor) {
        this.executor = executor;
    }
    /**
     * 线程池配置
     */
    @Bean("myThreadPoolTaskExecutor")
    public static Executor threadPoolTaskExecutor() {
        return use(threadNamePrefix).getExecutor();
    }

    private static ThreadPoolTaskExecutor createTP(String name) {
        return createTP(name,null);
    }
    private static ThreadPoolTaskExecutor createTP(String name,TPConfig xccpz) {
        if(xccpz == null){
            xccpz = new TPConfig();
        }
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        executor.setCorePoolSize(valByDef(xccpz.getCorePoolSize(),corePoolSize));
        // 设置最大线程数
        executor.setMaxPoolSize(valByDef(xccpz.getMaxPoolSize(),maxPoolSize));
        // 配置队列大小,缓存100个任务，视业务而定
        executor.setQueueCapacity(valByDef(xccpz.getQueueCapacity(),queueCapacity));
        // 设置线程活跃时间（秒）
        executor.setKeepAliveSeconds(valByDef(xccpz.getKeepAliveSeconds(),keepAliveSeconds));
        //核心线程允许超时
        executor.setAllowCoreThreadTimeOut(true);
        //设置默认线程名称
        executor.setThreadNamePrefix(name+"-");
        //初始化
        executor.initialize();
        return executor;
    }

    public static ThreadPool use(){
        return use(threadNamePrefix);
    }
    public static ThreadPool use(String name){
        return use(name,null);
    }

    /**
     * 获取线程池
     * @param name 名称
     * @param xccpz 现场池配置
     * @return 线程池
     */
    public static ThreadPool use(String name, TPConfig xccpz){
        ThreadPool t = threadMap.get(name);
        if(t==null){
            t = new ThreadPool(createTP(name,xccpz));
        }
        return t;
    }

    /**
     * 采用多线程执行
     */
    public void run(Runnable ra){
        executor.execute(ra);
    }

    @Override
    public int getQueueSize() {
        return executor.getThreadPoolExecutor().getQueue().size();
    }

    public void setCorePoolSize(int corePoolSize) {
        ThreadPool.corePoolSize = corePoolSize;
    }

    public void setMaxPoolSize(int maxPoolSize) {
        ThreadPool.maxPoolSize = maxPoolSize;
    }

    public void setKeepAliveSeconds(int keepAliveSeconds) {
        ThreadPool.keepAliveSeconds = keepAliveSeconds;
    }

    public void setQueueCapacity(int queueCapacity) {
        ThreadPool.queueCapacity = queueCapacity;
    }

    public void setThreadNamePrefix(String threadNamePrefix) {
        ThreadPool.threadNamePrefix = threadNamePrefix;
    }
}
